package modelo;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import modelo.exception.NoPuedeIniciarException;
import modelo.exception.SameStateException;
import modelo.exception.StatusChangeException;
import modelo.tareas.Tarea;
import modelo.util.Rol;

/**
 * 
 * @author Rocio
 *
 */
public class Usuario{
	
	
	
	// Variables  *********************************************************** //

	private String nombrePersona;
	private String mailPersona;
	private List<Rol>rolesAnteriores;
	private List<Tarea>tareasALasQuePertenezco;
	private Map<Proyecto, Rol> mimap= new HashMap<Proyecto, Rol>();//manera de asegurarme, que x proyecto solo posea un rol
	private int horasTrab =0;
	

	//Constructor *********************************************************** //
	public Usuario(String nombrePersona, String mailPersona) {
		this.nombrePersona = nombrePersona;
		this.mailPersona = mailPersona;
	}
	
	//Metodos     *********************************************************** //

	/**
	 * Numero de horas trabajados en total por un usuario.
	 */
	public int cantDeHorasTrabajadas(){
		for(Tarea t: this.tareasALasQuePertenezco){
			this.horasTrab += t.getDuracion();
		}
		return this.horasTrab;
		
	}
	
	/**
	 * cambiar a estado cerrado una tarea
	 * @param tarea
	 * @throws StatusChangeException 
	 * @throws SameStateException 
	 */
	public void cambiarAEstadoCerrado(Tarea tarea) throws SameStateException, StatusChangeException {
		tarea.cerrarTarea();
	}
	
	/**
	 * cambiar a estado iniciada una tarea
	 * @param tarea
	 * @throws StatusChangeException 
	 * @throws SameStateException 
	 * @throws NoPuedeIniciarException 
	 */
	public void cambiarAEstadoIniciada(Tarea tarea) throws SameStateException, StatusChangeException, NoPuedeIniciarException {
		tarea.iniciarTarea();
	}
	
	/**
	 * cambiar a estado en trabajo una tarea
	 * @param tarea
	 * @throws StatusChangeException 
	 * @throws SameStateException 
	 */
	public void cambiarAEstadoEnTrabajo(Tarea tarea) throws SameStateException, StatusChangeException{
		tarea.trabajarTarea();
	}
	
	/**
	 * cambiar a estado finalizado una tarea
	 * @param tarea
	 * @throws StatusChangeException 
	 * @throws SameStateException 
	 */
	public void cambiarAEstadoFinalizada(Tarea tarea) throws SameStateException, StatusChangeException {
		tarea.finalizarTarea();
	}
	
	/**
	 * cambiar a estado pausado una tarea
	 * @param tarea
	 * @throws StatusChangeException 
	 * @throws SameStateException 
	 */
	public void cambiarAEstadoPausado(Tarea tarea) throws SameStateException, StatusChangeException {
		tarea.pausarTarea();
	}
	
	
	//Auxiliares    *********************************************************** //
	
	
	//add
	/**
	 * agrega un rol al map(proyecto - rol)
	 * @param 
	 */
	public void addRolActual(Proyecto proyecto ,Rol rol){
		this.mimap.put(proyecto, rol);
	}
	
	/**
	 * agrega un rol a la lista de roles anteriores
	 * @param rol
	 */
	public void addRolAnterior(Rol rol){
		this.rolesAnteriores.add(rol);
	}

	/**
	 * agrega una Tarea a la lista de tareas
	 * @param tarea
	 */
	public void addTarea(Tarea tarea){
		this.tareasALasQuePertenezco.add(tarea);
	}
	
	/**
	 * agrega un proyecto a la lista de proyectos
	 * @param proyecto
	 */
	public void addProyecto(Proyecto proyecto){
		this.mimap.put(proyecto,new Rol("") );
	}
	
	//remove
	//realizo esto solo para asegurarme de no intentar extraer un Elemento que no se encuentra en la lista
	
	/**
	 * elimina un rol del map(proyecto - rol)
	 * @param 
	 */
	public void removeRolActual(Proyecto proyecto, Rol rol){
		if(this.mimap.containsValue(rol)){
			this.mimap.remove(proyecto);
			this.addRolAnterior(rol);
			this.addProyecto(proyecto);
		}
	}
	
	/**
	 * elimina un rol de la lista de roles anteriores
	 * @param 
	 */
	public void removeRolAnterior(Rol rol){
		if(this.getRolesAnteriores().contains(rol)){
			this.getRolesAnteriores().remove(rol);
		}
	}
	
	/**
	 * elimina una tarea de la lista de tareas 
	 * @param 
	 */
	public void removeTarea(Tarea tarea){
		if(this.getTareasALasQuePertenezco().contains(tarea)){
			this.getTareasALasQuePertenezco().remove(tarea);
		}
	}

	/**
	 * elimina una proyecto de la lista de proyectos
	 * @param 
	 */
	public void removeProyecto(Proyecto proyecto){
		if(this.mimap.containsKey(proyecto)){
			Rol x = this.mimap.get(proyecto);
			this.mimap.remove(proyecto);
			this.addRolAnterior(x);//al eliminar del sistema el proyecto debo guardar el rol que ocupaba como historico
			
			
		}
	}
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + horasTrab;
		result = prime * result
				+ ((mailPersona == null) ? 0 : mailPersona.hashCode());
		result = prime * result + ((mimap == null) ? 0 : mimap.hashCode());
		result = prime * result
				+ ((nombrePersona == null) ? 0 : nombrePersona.hashCode());
		result = prime * result
				+ ((rolesAnteriores == null) ? 0 : rolesAnteriores.hashCode());
		result = prime
				* result
				+ ((tareasALasQuePertenezco == null) ? 0
						: tareasALasQuePertenezco.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Usuario other = (Usuario) obj;
		if (horasTrab != other.horasTrab)
			return false;
		if (mailPersona == null) {
			if (other.mailPersona != null)
				return false;
		} else if (!mailPersona.equals(other.mailPersona))
			return false;
		if (mimap == null) {
			if (other.mimap != null)
				return false;
		} else if (!mimap.equals(other.mimap))
			return false;
		if (nombrePersona == null) {
			if (other.nombrePersona != null)
				return false;
		} else if (!nombrePersona.equals(other.nombrePersona))
			return false;
		if (rolesAnteriores == null) {
			if (other.rolesAnteriores != null)
				return false;
		} else if (!rolesAnteriores.equals(other.rolesAnteriores))
			return false;
		if (tareasALasQuePertenezco == null) {
			if (other.tareasALasQuePertenezco != null)
				return false;
		} else if (!tareasALasQuePertenezco
				.equals(other.tareasALasQuePertenezco))
			return false;
		return true;
	}

	//GET&SET     *********************************************************** //

	public String getNombrePersona() {
		return nombrePersona;
	}
	public void setNombrePersona(String nombrePersona) {
		this.nombrePersona = nombrePersona;
	}
	public String getMailPersona() {
		return mailPersona;
	}
	public void setMailPersona(String mailPersona) {
		this.mailPersona = mailPersona;
	}
	
	public List<Rol> getRolesAnteriores() {
		return rolesAnteriores;
	}
	public void setRolesAnteriores(List<Rol> rolesAnteriores) {
		this.rolesAnteriores = rolesAnteriores;
	}
	public List<Tarea> getTareasALasQuePertenezco() {
		return tareasALasQuePertenezco;
	}
	public void setTareasALasQuePertenezco(List<Tarea> tareasALasQuePertenezco) {
		this.tareasALasQuePertenezco = tareasALasQuePertenezco;
	}
	public Map<Proyecto, Rol> getMimap() {
		return mimap;
	}
	
	public void setMimap(Map<Proyecto, Rol> mimap) {
		this.mimap = mimap;
	}
	
	public int getHorasTrab() {
		return horasTrab;
	}
	
	public void setHorasTrab(int horasTrab) {
		this.horasTrab = horasTrab;
	}
	
}
